package classify

import (
	"encoding/binary"
	"fmt"
	"strconv"
	"strings"

	"gitee.com/thubcc/p2pgit/types"
)

// BasicClassify basic classify
type BasicClassify struct {
	Prefix uint64
	BitLen int
	drop   bool
}

// Hit interface
func (b *BasicClassify) Hit(hash types.Hash) bool {
	h := binary.BigEndian.Uint64(hash[:8])
	h >>= 64 - b.BitLen
	return !b.drop && h == b.Prefix
}

func (b *BasicClassify) String() string {
	return fmt.Sprintf("%02d-%016x", b.BitLen, b.Prefix)
}

// NewBasicClassifyFromString classify from file name
func NewBasicClassifyFromString(s string) (b *BasicClassify, err error) {
	ss := strings.Split(s, "-")
	if len(ss) != 2 {
		err = fmt.Errorf("Bad format: %s", s)
		return
	}
	var p uint64
	var bl int
	bl, err = strconv.Atoi(ss[0])
	if err != nil {
		return
	}
	p, err = strconv.ParseUint(ss[1], 16, 64)
	if err != nil {
		return
	}
	return &BasicClassify{
		Prefix: p,
		BitLen: bl,
	}, nil
}

// IdxKey interface
func (b *BasicClassify) IdxKey(hash types.Hash) (kp [4]byte) {
	l := b.BitLen / 8
	r := b.BitLen % 8
	h := binary.BigEndian.Uint64(hash[l : l+8])
	h >>= 32 - r
	var tb = make([]byte, 8)
	binary.BigEndian.PutUint64(tb, h)
	copy(kp[:], tb[4:8])
	return
}

// Drop interface
func (b *BasicClassify) Drop() {
	b.drop = true
}
